package database

import (
	"fitness/go-admin/internal/config"
	"fitness/go-admin/internal/model"
	"fmt"
	"log"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	gormlogger "gorm.io/gorm/logger"
)

func InitMySQL(cfg *config.Config) *gorm.DB {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local",
		cfg.Database.Username,
		cfg.Database.Password,
		cfg.Database.Host,
		cfg.Database.Port,
		cfg.Database.DBName,
		cfg.Database.Charset,
	)

	// 配置GORM日志
	var gormLogLevel gormlogger.LogLevel
	if cfg.Server.Mode == "debug" {
		gormLogLevel = gormlogger.Info // 开发环境：记录所有SQL
	} else {
		gormLogLevel = gormlogger.Warn // 生产环境：只记录慢查询和错误
	}

	// 自定义日志配置
	gormConfig := &gorm.Config{
		Logger: gormlogger.New(
			log.New(log.Writer(), "\r\n", log.LstdFlags), // 使用标准日志
			gormlogger.Config{
				SlowThreshold:             200 * time.Millisecond, // 慢查询阈值：200ms
				LogLevel:                  gormLogLevel,
				IgnoreRecordNotFoundError: true,                       // 忽略记录未找到错误
				Colorful:                  cfg.Server.Mode == "debug", // 开发环境彩色输出
			},
		),
	}

	db, err := gorm.Open(mysql.Open(dsn), gormConfig)
	if err != nil {
		log.Fatalf("数据库连接失败: %v", err)
	}

	sqlDB, err := db.DB()
	if err != nil {
		log.Fatalf("获取数据库实例失败: %v", err)
	}

	// 设置数据库连接池参数（优化配置）
	sqlDB.SetMaxIdleConns(cfg.Database.MaxIdleConns)                                    // 空闲连接池大小：50
	sqlDB.SetMaxOpenConns(cfg.Database.MaxOpenConns)                                    // 最大连接数：200
	sqlDB.SetConnMaxLifetime(time.Second * time.Duration(cfg.Database.ConnMaxLifetime)) // 连接最大生命周期：30分钟
	sqlDB.SetConnMaxIdleTime(time.Second * time.Duration(cfg.Database.ConnMaxIdleTime)) // 空闲连接最大生命周期：5分钟

	// 数据库连接池优化建议注释
	log.Printf("数据库连接池配置 - 空闲连接数: %d, 最大连接数: %d, 连接生命周期: %ds, 空闲超时: %ds",
		cfg.Database.MaxIdleConns,
		cfg.Database.MaxOpenConns,
		cfg.Database.ConnMaxLifetime,
		cfg.Database.ConnMaxIdleTime)

	// 自动迁移数据表 - 分步迁移确保外键依赖顺序
	// 第一步：迁移基础表（无外键依赖）
	if err := db.AutoMigrate(
		&model.User{},
		&model.Role{},
		&model.Permission{},
		&model.RolePermission{},
		&model.Member{},
		&model.Course{},
		&model.Coach{},
		&model.Plan{},
		&model.CourseBooking{}, // 课程预约表
		// 会员卡相关表
		&model.MembershipCardType{}, // 会员卡类型表
		&model.MembershipCard{},     // 会员卡表
		&model.RechargeRecord{},     // 充值记录表
		&model.ConsumptionRecord{},  // 消费记录表
		&model.BalanceLog{},         // 余额日志表
		// 文件相关表
		&model.FileRecord{},       // 文件记录表
		&model.TrainingPhoto{},    // 训练照片表
		&model.CoachCertificate{}, // 教练证书表
	); err != nil {
		log.Fatalf("数据表迁移失败（基础表）: %v", err)
	}

	// 第二步：迁移客服聊天会话表（必须在消息表之前）
	if err := db.AutoMigrate(
		&model.ChatSession{}, // 客服会话表
	); err != nil {
		log.Fatalf("数据表迁移失败（聊天会话表）: %v", err)
	}

	// 第三步：迁移依赖会话表的消息表
	if err := db.AutoMigrate(
		&model.ChatMessage{}, // 聊天消息表（依赖ChatSession）
	); err != nil {
		log.Fatalf("数据表迁移失败（聊天消息表）: %v", err)
	}

	// 第四步：迁移其他聊天相关表
	if err := db.AutoMigrate(
		&model.ChatQuickReply{}, // 快捷回复表
		&model.SensitiveWord{},  // 敏感词表
		// 表情相关表
		&model.EmojiCategory{}, // 表情分类表
		&model.Emoji{},         // 表情表
	); err != nil {
		log.Fatalf("数据表迁移失败（其他聊天相关表）: %v", err)
	}

	// 第五步：迁移评价反馈相关表
	if err := db.AutoMigrate(
		&model.CourseReview{},  // 课程评价表
		&model.CoachRating{},   // 教练评分表
		&model.Feedback{},      // 意见反馈表
		&model.ReviewReply{},   // 评价回复表
		&model.ReviewHelpful{}, // 评价有用记录表
		&model.ReviewReport{},  // 评价举报表
	); err != nil {
		log.Fatalf("数据表迁移失败（评价反馈相关表）: %v", err)
	}

	// 第六步：迁移签到打卡相关表
	if err := db.AutoMigrate(
		&model.Checkin{}, // 签到记录表
		&model.Gym{},     // 健身房信息表
	); err != nil {
		log.Fatalf("数据表迁移失败（签到打卡相关表）: %v", err)
	}

	// 第七步：迁移通知推送相关表
	if err := db.AutoMigrate(
		&model.Notification{},        // 通知记录表
		&model.Template{},            // 通知模板表
		&model.Announcement{},        // 系统公告表
		&model.NotificationSetting{}, // 用户订阅配置表
	); err != nil {
		log.Fatalf("数据表迁移失败（通知推送相关表）: %v", err)
	}

	// 第八步：迁移系统管理相关表
	if err := db.AutoMigrate(
		&model.OperationLog{}, // 操作日志表
		&model.Menu{},         // 菜单表
		&model.DictType{},     // 字典类型表
		&model.DictData{},     // 字典数据表
	); err != nil {
		log.Fatalf("数据表迁移失败（系统管理相关表）: %v", err)
	}

	// 初始化基础角色
	initRoles(db)

	log.Printf("数据库连接成功 - 连接池配置: 空闲连接数=%d, 最大连接数=%d, 连接生命周期=%ds, 空闲超时=%ds",
		cfg.Database.MaxIdleConns,
		cfg.Database.MaxOpenConns,
		cfg.Database.ConnMaxLifetime,
		cfg.Database.ConnMaxIdleTime)
	return db
}

// initRoles 初始化基础角色
func initRoles(db *gorm.DB) {
	var count int64
	db.Model(&model.Role{}).Count(&count)
	if count > 0 {
		return
	}

	roles := []model.Role{
		{ID: 1, Name: "超级管理员", Code: "admin", Description: "系统最高权限", Status: 1},
		{ID: 2, Name: "教练", Code: "coach", Description: "教练角色", Status: 1},
		{ID: 3, Name: "普通用户", Code: "member", Description: "普通会员用户", Status: 1},
	}

	for _, role := range roles {
		db.Create(&role)
	}

	log.Println("基础角色初始化完成")
}
